// 处理数据库
const {
	dbQuery
} = require('../db/index');
// 处理加密
const bcrypt = require('bcryptjs');
// 处理验证
const joi = require('joi');
// 处理响应
const {
	sendError,
	sendSuccess
} = require('../tools/sendFunction')

// 处理token
const jwtoken = require('jsonwebtoken');


// 设定验证规则
var guiZe = joi.object({
	username: joi.string().alphanum().min(1).max(10).required().error(new Error('username不符合验证规则')),
	password: joi.string().required().regex(/^[\S]{6,12}$/).error(new Error('password不符合验证规则'))
})

// 注册
exports.register = async (req, res, next) => {
	const userInfo = req.body;

	// 判断用户名或密码是否为空
	if (!userInfo.username || !userInfo.password) {
		sendError(res, 400, '用户名或密码不能为空!');
		return;
	}

	// 验证用户名是否被占用
	try {
		var result = await dbQuery('select * from users where username=?', [userInfo.username])
	} catch (error) {
		next(error);
	}
	// 用户名被占用
	if (result.length !== 0) {
		sendError(res, 400, '用户名被占用，请更换其他用户名!');
		return;
	}

	// 用户名不被占用 
	// 验证请求参数
	try {
		await guiZe.validateAsync({
			username: userInfo.username,
			password: userInfo.password
		})
	} catch (error) {
		next(error);
		return;
	}

	// 用户名不被占用且验证规则通过
	// 加密密码
	let salt = await bcrypt.genSalt(10);
	userInfo.password = await bcrypt.hash(userInfo.password, salt);
	// 插入数据
	try {
		var result2 = await dbQuery('insert into users (username,password) values (?,?)', [userInfo.username, userInfo.password])
	} catch (error) {
		next(error);
		return;
	}
	if (result2.affectedRows !== 1) {
		sendError(res, 200, '注册用户失败，请稍后再试!')
		return;
	}
	sendSuccess(res, '注册成功!');
}

exports.login = async (req, res, next) => {
	const userInfo = req.body;

	// 验证请求参数
	try {
		await guiZe.validateAsync({
			username: userInfo.username,
			password: userInfo.password
		})
	} catch (error) {
		next(error)
		return;
	}

	// 是否有该用户名
	try {
		var result = await dbQuery('select * from users where username = ?', [userInfo.username])
	} catch (error) {
		next(error)
		return;
	}
	// 没有此用户名
	if (result.length == 0) {
		sendError(res, 200, '登录失败,请注册后重新登录!')
		return;
	}

	// 有用户名
	// 验证密码是否正确
	let isValid = await bcrypt.compare(userInfo.password, result[0].password);
	// 如果不正确
	if (!isValid) {
		sendError(res, 200, '用户名或密码错误');
	} else {
		// 如果正确
		// 生成token字符串
		// 定义一个加密字符串
		let str = 'secret';
		sendSuccess(res, '登陆成功!', {
			token: 'Bearer ' + jwtoken.sign({
				username: result[0].username,
				id: result[0].id,
				nickname: result[0].nickname,
				email: result[0].email
			}, str, {
				expiresIn: '24h'
			})
		})
	}
}